linux sockaddr 您所在的位置:网站首页 sockaddr_un 头文件 linux sockaddr

linux sockaddr

#linux sockaddr| 来源: 网络整理| 查看: 265

1、socket

不管是 Windows 还是 Linux,都使用 socket() 函数来创建套接字。socket() 在两个平台下的参数是相同的,不同的是返回值:

(1)Linux 中的一切都是文件,每个文件都有一个整数类型的文件描述符;socket 也是一个文件,也有文件描述符。使用 socket() 函数创建套接字以后,返回值就是一个 int 类型的文件描述符。

(2)Windows 会区分 socket 和普通文件,它把 socket 当做一个网络连接来对待,调用 socket() 以后,返回值是 SOCKET 类型,用来表示一个套接字。

Linux 下的 socket() 函数

在 Linux 下使用 头文件中 socket() 函数来创建套接字,原型为:

int socket(int af, int type, int protocol);

参数:

af 为地址族(Address Family),也就是 IP 地址类型,常用的有 AF_INET 和 AF_INET6。

type 为数据传输方式/套接字类型,常用的有 SOCK_STREAM(流格式套接字/面向连接的套接字) 和 SOCK_DGRAM(数据报套接字/无连接的套接字)

protocol 表示传输协议,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP,分别表示 TCP 传输协议和 UDP 传输协议

Linux下创建套接字:

int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //IPPROTO_TCP表示TCP协议

2、sockaddr和sockaddr_in详解

struct sockaddr和struct sockaddr_in这两个结构体用来处理网络通信的地址

1、sockaddr

sockaddr在头文件#include 中定义,sockaddr的缺陷是:sa_data把目标地址和端口信息混在一起了,如下:

struct sockaddr {

sa_family_t sin_family;//地址族

char sa_data[14]; //14字节,包含套接字中的目标地址和端口信息

};

2、sockaddr_in

sockaddr_in在头文件#include或#include 中定义,该结构体解决了sockaddr的缺陷,把port和addr 分开储存在两个变量中,如下:

8496eb2c35684c10e1cf50679a9fd3c9.png

sin_port和sin_addr都必须是网络字节序(NBO),一般可视化的数字都是主机字节序(HBO)。

3、总结

二者长度一样,都是16个字节,即占用的内存大小是一致的,因此可以互相转化。二者是并列结构,指向sockaddr_in结构的指针也可以指向sockaddr。

sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。

sockaddr_in 是internet环境下套接字的地址形式。所以在网络编程中我们会对sockaddr_in结构体进行操作,使用sockaddr_in来建立所需的信息,最后使用类型转化就可以了。一般先把sockaddr_in变量赋值后,强制类型转换后传入用sockaddr做参数的函数:sockaddr_in用于socket定义和赋值;sockaddr用于函数参数。

#include #include #include #include int main(int argc,char **argv)

{

int sockfd;

struct sockaddr_in mysock;

sockfd = socket(AF_INET,SOCK_STREAM,0); //获得fd

bzero(&mysock,sizeof(mysock)); //初始化结构体

mysock.sin_family = AF_INET; //设置地址家族

mysock.sin_port = htons(800); //设置端口

mysock.sin_addr.s_addr = inet_addr("192.168.1.0"); //设置地址

bind(sockfd,(struct sockaddr *)&mysock,sizeof(struct sockaddr); /* bind的时候进行转化 */

... ...

return 0;

}

3、inet_addr()

描述:

inet_addr()作用是将一个IP字符串转化为一个网络字节序的整数值

返回值:

若无错误发生,inet_addr()返回一个无符号长整型数,其中以适当字节顺序存放Internet地址。如果传入的字符串不是一个合法的Internet地址,如“a.b.c.d”地址中任一项超过255,那么inet_addr()返回INADDR_NONE

4、gethostbyname

函数原型:

struct hostent* gethostbyname(const char *name);

调用函数成功返回一个hostent结构体

struct hostent

{

char *h_name;

char ** h_aliases;

short h_addrtype;

short h_length;

char ** h_addr_list;

};

测试代码:

#include#include#include#include#include#include#include#include#include#include#include#include int main(int argc,char *argv[])

{

int optret;

char *ipname = NULL;

char ip[50];

struct hostent *gethost = NULL;

int file_fd;

char buf[50];

char *ptrf;

char *ptrb;

int n;

char fptr[50];

const char *ptr = NULL;

struct in_addr inAddr;

while((optret = getopt(argc,argv,"i:")) != -1)

{

switch(optret)

{

case 'i':

ipname = optarg;

printf("option = i,the ipname is:%s\n",optarg);

break;

}

}

gethost = gethostbyname(ipname);

if (NULL == gethost)

{

perror("get ipaddr fail!");

return -1;

}

printf("get host successfully!\n");

memset(ip,0,sizeof(ip));

ptr = inet_ntop(gethost->h_addrtype,gethost->h_addr_list[0],ip,sizeof(ip));

printf("DNS ip is:%s\n",ptr);

system("ping studio.iot-yun.com -c 2 >> /home/deepin/APUE/malunkun/test/.domain.log");

file_fd=open("/home/deepin/APUE/malunkun/test/.domain.log",O_RDONLY,644);

if (file_fd < 0)

{

perror("open file fail!\n");

}

read(file_fd,buf,sizeof(buf));

close(file_fd);

ptrf = strstr(buf,"(");

ptrf += 1;

ptrb = strstr(buf,")");

n = strlen(ptrf)-strlen(ptrb);

strncpy(fptr,ptrf,n);

printf("ping ip is:%s\n",fptr);

return 0;

}

输出:

844641f7f5679d42bc12185aad197d32.png

使用输出的IP地址去访问网站,发现显示的也是百度

434cb1b823434d2be529e2666c915c2d.png

5、getsockopt和setsockopt函数

这两个函数仅用于套接字。

函数原型:

#include #include int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);

sockfd:必须指向一个打开的套接字描述符

level:指定系统中解释选项的代码或为通用套接字代码,或为某个特定于协议的代码(例如IPv4IPv6、TCP或SCTP)。

optval:指向某个变量(*optval)的指针,setsockopt从optval中取得选项设置的新值,getsockopt则把以获取的选项当前值存入optval。

optlen:指定*optval的大小

套接字选项的汇总可以查看unix网络编程(卷1)151页 图7-1和图7-2

f8fa812bac48a0d422bb79687b4cff43.png

6d71f58cfecdf881783fb6f6b1c0824f.png

0cd904d3b21101e0b992a87baae68cb3.png

7c3552eaeab4c8e8ffd0215d9d373722.png



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有